home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Trading on the Edge
/
Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin
/
pc
/
mac_file
/
vendor_d
/
neuralwa
/
nw2v50
/
automate.c
< prev
next >
Wrap
Text File
|
1993-08-23
|
65KB
|
1,695 lines
/****************************************************************************/
/* */
/* Automate.c - A User Control program to batch-process many of the */
/* Professional II/PLUS commands. Multiple network names and tasks to be */
/* performed are read from file automate.dat, with results written back */
/* into automate.dat. See shipped automate.dat for example of syntax. */
/* */
/* This program requires version 5.0 of NeuralWorks Professional II/PLUS. */
/* */
/* version 1.0 Copyright 1993 by NeuralWare Inc. */
/* */
/* edit history... */
/* 07/31/93 - v1.0 release. Bob Everly */
/* */
/****************************************************************************/
#define UIO_SERVER 1
#define SERVER_EMULATOR_FILE 1
#define SKIP_COMPAT_DATA 1
#include "userutl.h"
#include "uio_strc.h"
#include "uio_tran.h"
#include "uio_reqs.pro"
#include "uio_cmds.pro"
/*********** global variables and user #includes are entered here **********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h> /* for tolower() */
NINT preScan ARGLIST (( ));
NINT processOneTask ARGLIST (( NINT ));
NINT disableOutput ARGLIST (( ));
NINT runHoldout ARGLIST (( ));
NINT parseString ARGLIST (( TEXT **, TEXT *, TEXT * ));
NINT parseLong ARGLIST (( TEXT **, SL * ));
NINT parseInteger ARGLIST (( TEXT **, NINT * ));
NINT parseReal ARGLIST (( TEXT **, SREAL * ));
NINT fileNotFound ARGLIST (( TEXT *, TEXT *, NINT ));
VOID showMsg ARGLIST (( TEXT *, NINT ));
#ifdef MAC
OSErr SetTypeAndCreator ARGLIST(( char *, char *, char *, short));
#endif /* MAC */
#define DATLINELEN 500 /* max line length in automate.dat */
#define DISABLEPES 50 /* max PEs disabled at once (must fit in DATLINELEN) */
#define MAXFILESPEC 50 /* max chrs in a filename */
#define NNPLINELEN 1500 /* max line length of *.nnp (Conf.Matrix output) */
#define OPEN 1 /* taskID's - understood tasks */
#define LEARN 2
#define RECALL 3
#define TEST 4
#define SAVEBEST 5
#define INITIALIZE 6
#define RANDOMSEED 7
#define DISABLE 8
#define DISABLE_ALL 9
#define SAVENET 10
#define SETCMD 11 /* LearnFile, RecallFile, TestFile, Disable */
#define HOLDOUT 12
#define TASK_OK 0 /* Task OK */
#define TASK_ERROR -1 /* Task Error */
#define TASK_INTRPT -2 /* Task Interrupted */
#ifdef THINK_C
#define EolChr "\r"
#else
#define EolChr "\n"
#endif
#define USER_INTRPT 0x0002
TEXT NetworkFile[MAXFILESPEC]; /* net filename, for open */
TEXT SavenetFile[MAXFILESPEC]; /* net filename, for savnet */
TEXT LearnFile[MAXFILESPEC]; /* alternate *.nna file, for learn & savebest */
TEXT TestFile[MAXFILESPEC]; /* alternate *.nna file, for recall, test, disable */
SL Long1, Long2, Long3; /* args for learn & savebest */
SREAL SbPruneTolerance; /* prune tolerance for savebest pruning */
NINT SbPruneMaxPEs; /* max number of PEs to prune during savebest pruning */
NINT RandomSeed; /* arg for randomseed task */
NINT PeNumbers[DISABLEPES]; /* pe list, for disable */
NINT IsSetLearn, IsSetTest; /* flags== 1 for alternate learn/recall/test files */
NINT IsSetDisable; /* flag == 1 for disable-PEs-and-save-net */
NINT FirstDisableTask; /* flag == 1 upon first encounter of disable in this net */
NINT NumInputPEs; /* input pe count, for disable */
SREAL BaselineSum; /* sum of R values for disable's baseline test */
SREAL SigmaStart, SigmaStop, SigmaStep; /* varies PNN/GRNN holdout Sigma Scale */
NINT xSize, xChrSize, ySize, yChrSize; /* graphics characteristics */
/********************* end of user global definitions **********************/
#ifdef MAC
#include "macuio.redef"
#endif
/**************************************************************************/
/* Only functions UIO_Init(), UIO_Term() and especially UIO_Attention() */
/* are used by a User Control program. Code is added into these three */
/* functions. User written C functions can also be added and called. */
/**************************************************************************/
NINT UIO_Init(file)
TEXT *file;
{
/* Certain compilers yield warnings when variables are declared within */
/* functions but never used; hence the 'compiler be quiet!' lines. */
file=file; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Term(process)
NINT process;
{
process = process; /* compiler be quiet! */
return(UIO_OK);
}
/**************************************************************************/
/* UIO_Attention() is used here as a 'driver', reading and parsing */
/* tasks from automate.dat. */
/**************************************************************************/
NINT UIO_Attention()
{
FILE *inputFile; /* extracts data from automate.dat */
FILE *tmpFile; /* modified automate.dat including network run results */
TEXT input[DATLINELEN]; /* one text line from automate.dat */
TEXT *sp, *sp2, *spend; /* string pointers into various arrays */
NINT taskID; /* Pro II/PLUS task to be performed */
NINT runResult; /* return from processOneTask(); controls execution */
NINT i;
/* perform all validations, file checks, and task syntax checks */
if ( (preScan ()) != UIO_OK) {
#ifdef THINK_C
/* MAC version is multi-segment. Assume str.c is in second segment */
UnloadA4Seg(strcpy);
#endif
return (UIO_ERROR);
}
/* loop until all networks have been processed */
while (1) {
runResult = TASK_OK;
/* open files */
inputFile = fopen ("automate.dat","r");
remove ("automate.tmp");
tmpFile = fopen ("automate.tmp", "w");
while ((sp=fgets (input, DATLINELEN, inputFile)) != 0) {
/* skip spaces, blank lines and comments. Copy such lines into automate.tmp */
for (; *sp <= 0x20 && *sp != '\0'; sp++);
if (*sp != '!' && *sp != '\0')
break;
else
fprintf (tmpFile, "%s", input);
}
/* exit program if all tasks in automate.dat have been processed */
if (sp == (char *)0)
break;
/* we have read a command from automate.dat to be processed. */
/* parse the input line, reading the task */
for (sp = input; *sp <= 0x20 && *sp != '\0'; sp++); /* skip spaces, etc */
sp2 = sp; /* sp2 points to start of task string */
for (; *sp > 0x20 && *sp != ',' && *sp != '!'; sp++)
*sp = (TEXT) tolower (*sp);
i = (NINT) *sp; /* temporarily replace next chr with end of string */
*sp = '\0';
if ( (strncmp (sp2, "open" , 4 )) == 0) taskID = OPEN;
else if ( (strncmp (sp2, "learn" , 4 )) == 0) taskID = LEARN;
else if ( (strncmp (sp2, "train" , 4 )) == 0) taskID = LEARN;
else if ( (strncmp (sp2, "recall" , 4 )) == 0) taskID = RECALL;
else if ( (strncmp (sp2, "test" , 4 )) == 0) taskID = TEST;
else if ( (strncmp (sp2, "savebest" , 5 )) == 0) taskID = SAVEBEST;
else if ( (strncmp (sp2, "initialize", 4 )) == 0) taskID = INITIALIZE;
else if ( (strncmp (sp2, "randomseed", 4 )) == 0) taskID = RANDOMSEED;
else if ( (strncmp (sp2, "seed" , 4 )) == 0) taskID = RANDOMSEED;
else if ( (strncmp (sp2, "disable" , 4 )) == 0) taskID = DISABLE;
else if ( (strncmp (sp2, "savenet" , 5 )) == 0) taskID = SAVENET;
else if ( (strncmp (sp2, "set" , 3 )) == 0) taskID = SETCMD;
else if ( (strncmp (sp2, "holdout" , 4 )) == 0) taskID = HOLDOUT;
*sp = (TEXT) i; /* restore the chr */
if (*sp == ',')
sp++; /* skip single comma */
for (; *sp <= 0x20 && *sp != '\0'; sp++); /* skip spaces after task id */
/* parse remainder of line depending on the task. 'sp' points to first */
/* character in first parameter, or end of string. 'sp2' in not set */
switch (taskID) {
case OPEN:
parseString (&sp, NetworkFile, &NetworkFile[MAXFILESPEC]);
IsSetLearn = 0; /* open cmd kills previous 'set' commands */
IsSetTest = 0;
IsSetDisable = 0;
FirstDisableTask = 1;
SavenetFile[0] = '\0'; /* kill any previous SAVENET filename */
break;
/* savenet will overwrite the network currently in use if a new */
/* network filename is not specified */
case SAVENET:
parseString (&sp, SavenetFile, &SavenetFile[MAXFILESPEC]);
if (SavenetFile[0] == '\0')
strcpy (SavenetFile, NetworkFile);
break;
case LEARN:
parseLong (&sp, &Long1);
break;
case RECALL: /* these tasks have no parameters */
case TEST:
case INITIALIZE:
break;
case SAVEBEST:
parseLong (&sp, &Long1);
parseLong (&sp, &Long2);
parseLong (&sp, &Long3);
parseReal (&sp, &SbPruneTolerance);
parseInteger (&sp, &SbPruneMaxPEs);
break;
case DISABLE:
/* differentiate between tasks DISABLE and DISABLE_ALL */
if ( (strncmp (sp, "all", 3 ) == 0) ||
(strncmp (sp, "each", 4 ) == 0) ||
(strncmp (sp, "every",5 ) == 0) ) {
taskID = DISABLE_ALL;
break;
}
/* read remaining numeric fields (pe numbers) */
for (i=0; i < DISABLEPES; i++)
if ( (parseInteger (&sp, &PeNumbers[i])) == 1 )
break;
break;
case SETCMD:
sp2 = sp; /* sp2 points to start of task string */
for (; *sp > 0x20 && *sp != ',' && *sp != '!'; sp++)
*sp = (TEXT) tolower (*sp);
i = (NINT) *sp; /* temporarily replace next chr with end of string */
*sp = '\0';
IsSetLearn = 0;
IsSetTest = 0;
IsSetDisable= 0;
if ( (strncmp (sp2, "learnfile" , 4 )) == 0) IsSetLearn = 1;
else if ( (strncmp (sp2, "recallfile", 4 )) == 0) IsSetTest = 1;
else if ( (strncmp (sp2, "testfile" , 4 )) == 0) IsSetTest = 1;
else if ( (strncmp (sp2, "disable" , 4 )) == 0) IsSetDisable=1;
*sp = (TEXT) i; /* restore the chr */
if (*sp == ',')
sp++; /* skip single comma */
for (; *sp <= 0x20 && *sp != '\0'; sp++); /* skip spaces after task id */
if (IsSetLearn) {
sp2 = LearnFile;
parseString (&sp, sp2, &sp2[MAXFILESPEC]);
}
else if (IsSetTest) {
sp2 = TestFile;
parseString (&sp, sp2, &sp2[MAXFILESPEC]);
}
/* else if (IsSetDisable) break -- this set has no args */
break;
case RANDOMSEED:
parseInteger (&sp, &RandomSeed);
break;
case HOLDOUT:
parseReal (&sp, &SigmaStart);
parseReal (&sp, &SigmaStop);
parseReal (&sp, &SigmaStep);
break;
} /* end switch */
/* process the task */
fclose (tmpFile);
runResult = processOneTask (taskID);
/* mark this line as being processed */
tmpFile = fopen ("automate.tmp", "a");
if (runResult == TASK_OK)
fprintf (tmpFile, "! Successful: %s", input);
else if (runResult == TASK_INTRPT)
fprintf (tmpFile, "! Interrupted: %s", input);
else
fprintf (tmpFile, "! FAILURE: %s", input);
/* now copy the remaining text into the .tmp file and swap filenames */
while (fgets (input, DATLINELEN, inputFile) != 0)
fprintf (tmpFile, "%s", input);
fclose (tmpFile);
fclose (inputFile);
remove ("automate.dat");
rename ("automate.tmp", "automate.dat");
if (runResult == TASK_INTRPT) {
PutStr("Do you wish to abort all tasks? (Y/n)");
sp = GetStr( );
if (*sp != 'n' && *sp != 'N')
break;
}
} /* end while (1) */
fclose (tmpFile);
remove ("automate.tmp");
fclose (inputFile);
#ifdef MAC
SetTypeAndCreator ("automate.dat", "TEXT", "ttxt", -1);
#ifdef THINK_C
/* MAC version is multi-segment. Assume str.c is in second segment */
UnloadA4Seg(strcpy);
#endif
#endif
return (UIO_OK); /* normal end of program */
}
/**************************************************************************/
/* preScan() reads and parses tasks in automate.dat to ensure there are */
/* no command errors or syntax errors present. */
/**************************************************************************/
NINT preScan()
{
FILE *inputFile; /* extracts data from automate.dat */
FILE *tmpFile; /* modified automate.dat including network run results */
TEXT input[DATLINELEN]; /* one text line from automate.dat */
TEXT *sp, *sp2, *spend; /* string pointers into various arrays */
TEXT quoteChr; /* filenames can be quoted (" or ') in automate.dat */
NINT parsingError; /* flag == 1 if parsing error in task request */
NINT numErrors; /* counter of parsingErrors */
NINT taskID; /* Pro II/PLUS task to be performed */
NINT runResult; /* return from processOneTask(); controls execution */
NINT i;
numErrors = 0;
/* loop until all networks have been processed */
runResult = UIO_OK;
/* open automate.dat */
if ( (inputFile = fopen ("automate.dat","r")) == (FILE *)0 ) {
showMsg ("ERROR: Automate.dat must exist; press Enter to exit...", 0);
GetStr ();
return (UIO_EXIT);
}
else
PutStr ("Scanning automate.dat for syntax errors... ");
remove ("automate.tmp");
if ( (tmpFile = fopen ("automate.tmp", "w")) == (FILE *)0) {
showMsg ("ERROR: Unable to create automate.tmp; press Enter to exit...", 0);
GetStr ();
return (UIO_EXIT);
}
while (runResult != UIO_EXIT) {
while ((sp=fgets (input, DATLINELEN, inputFile)) != 0) {
/* skip spaces, blank lines and comments. Copy such lines into automate.tmp */
for (sp = input; *sp <= 0x20 && *sp != '\0'; sp++);
if (*sp != '!' && *sp != '\0')
break;
else
fprintf (tmpFile, "%s", input);
}
if (sp == (char *)0) {
/* automate.dat now has no commands remaining to be processed. If we have */
/* processed any networks, then exit this routine. If the file existed but */
/* had nothing to be processed, display an error and exit. */
if (NetworkFile[0] == '\0') {
showMsg ("ERROR: Automate.dat contains no new requests; press Enter to exit...", 0);
GetStr ();
runResult = UIO_EXIT;
}
else /* if here, we've finished the last network */
runResult = UIO_OK; /* in automate.dat; time to exit this routine */
break; /* escape while loop, goto end of this routine */
}
/* we have read a command from automate.dat to be processed. */
/* parse the input line, reading the task */
for (sp = input; *sp <= 0x20 && *sp != '\0'; sp++); /* skip spaces, etc */
sp2 = sp; /* sp2 points to start of task string */
for (; *sp > 0x20 && *sp != ',' && *sp != '!'; sp++)
*sp = (TEXT) tolower (*sp);
i = (NINT) *sp; /* temporarily replace next chr with end of string */
*sp = '\0';
taskID = -999; /* init to unknown taskID */
if ( (strncmp (sp2, "open" , 4 )) == 0) taskID = OPEN;
else if ( (strncmp (sp2, "learn" , 4 )) == 0) taskID = LEARN;
else if ( (strncmp (sp2, "train" , 4 )) == 0) taskID = LEARN;
else if ( (strncmp (sp2, "recall" , 4 )) == 0) taskID = RECALL;
else if ( (strncmp (sp2, "test" , 4 )) == 0) taskID = TEST;
else if ( (strncmp (sp2, "savebest" , 5 )) == 0) taskID = SAVEBEST;
else if ( (strncmp (sp2, "initialize", 4 )) == 0) taskID = INITIALIZE;
else if ( (strncmp (sp2, "randomseed", 4 )) == 0) taskID = RANDOMSEED;
else if ( (strncmp (sp2, "seed" , 4 )) == 0) taskID = RANDOMSEED;
else if ( (strncmp (sp2, "disable" , 4 )) == 0) taskID = DISABLE;
else if ( (strncmp (sp2, "savenet" , 5 )) == 0) taskID = SAVENET;
else if ( (strncmp (sp2, "set" , 3 )) == 0) taskID = SETCMD;
else if ( (strncmp (sp2, "holdout" , 4 )) == 0) taskID = HOLDOUT;
*sp = (TEXT) i; /* restore the chr */
if (*sp == ',')
sp++; /* skip single comma */
for (; *sp <= 0x20 && *sp != '\0'; sp++); /* skip spaces after task id */
/* parse remainder of line depending on the task. 'sp' points to first */
/* character in first parameter, or end of string. 'sp2' in not set */
parsingError = 0; /* assume success */
switch (taskID) {
/* An OPEN task really requires a network name */
case OPEN:
if ( (parsingError = parseString (&sp, NetworkFile, &NetworkFile[MAXFILESPEC])) == 1) {
fprintf (tmpFile, "FAILURE: missing quote -> %s", input);
break;
}
if (NetworkFile[0] == '\0') {
fprintf (tmpFile, "FAILURE: missing filename -> %s", input);
parsingError = 1;
break;
}
/* the network is opened here as a final check, and also must be */
/* open for disable to check it's PE list */
if (ug_loadnet (NetworkFile) != UIO_OK) {
fprintf (tmpFile, "FAILURE: error opening network -> %s", input);
parsingError = 1;
break;
}
IsSetDisable = 0;
IsSetLearn = 0;
IsSetTest = 0;
break;
/* savenet will overwrite the network currently in use if a new */
/* network filename is not specified */
case SAVENET:
if ( (parsingError = parseString (&sp, SavenetFile, &SavenetFile[MAXFILESPEC])) == 1) {
fprintf (tmpFile, "FAILURE: missing quote -> %s", input);
SavenetFile[0] = '\0';
}
break;
case LEARN:
if ( (parsingError = parseLong (&sp, &Long1)) == 1)
fprintf (tmpFile, "FAILURE: learn count missing -> %s", input);
break;
case RECALL: /* these tasks have no parameters */
case TEST:
case INITIALIZE:
break;
case SAVEBEST:
if ( (parsingError = parseLong (&sp, &Long1)) == 1) {
fprintf (tmpFile, "FAILURE: learn count missing -> %s", input);
break;
}
if ( (parsingError = parseLong (&sp, &Long2)) == 1) {
fprintf (tmpFile, "FAILURE: test frequency missing -> %s", input);
break;
}
if (Long2 > Long1) {
fprintf (tmpFile, "FAILURE: test freq > learn count-> %s", input);
parsingError = 1;
break;
}
Long3 = 0; /* three optional parameters */
SbPruneTolerance = 0.0;
SbPruneMaxPEs = 0;
parseLong (&sp, &Long3); /* this allows #retries to be zero, but */
/* will miss bad entries (i.e. alpha chrs) */
parsingError = parseReal (&sp, &SbPruneTolerance);
if (!parsingError)
parsingError = parseInteger (&sp, &SbPruneMaxPEs);
if (!parsingError) /* okay if all 3 optional values are specified */
break;
if (SbPruneTolerance == 0.0 && SbPruneMaxPEs == 0) {
parsingError = 0; /* okay if last 2 optional values are unspecified */
break;
}
fprintf (tmpFile, "FAILURE: # of retries missing? -> %s", input);
parsingError = 1; /* error if 4 of 5 fields were entered */
break;
case DISABLE:
/* differentiate between tasks DISABLE and DISABLE_ALL */
if ( (strncmp (sp, "all", 3 ) == 0) ||
(strncmp (sp, "each", 4 ) == 0) ||
(strncmp (sp, "every",5 ) == 0) ) {
taskID = DISABLE_ALL;
sp = &input[strlen (input)];
break;
}
/* read remaining numeric fields (pe numbers) */
for (i=0; i < DISABLEPES; i++)
if (parseInteger(&sp, &PeNumbers[i]))
break;
if (PeNumbers[0] == 0) {
fprintf (tmpFile, "FAILURE: no PEs listed -> %s", input);
parsingError = 1;
break;
}
/* check the PE list for mistakes */
sp2 = SavenetFile; /* using for junk storage */
NumInputPEs = 0; /* only 1 arg below is wanted */
ug_rdnetinf (&i, &NumInputPEs, &i, &i, &sp2, &sp2); /* assumes net is opened */
for (i=0; i < DISABLEPES && PeNumbers[i] != 0; i++)
if (PeNumbers[i] < 2 || PeNumbers[i] > NumInputPEs+1) {
fprintf (tmpFile, "FAILURE: non-existent input PE -> %s", input);
parsingError = 1;
break;
}
break;
case SETCMD:
sp2 = sp; /* sp2 points to start of task string */
for (; *sp > 0x20 && *sp != ',' && *sp != '!'; sp++)
*sp = (TEXT) tolower (*sp);
i = (NINT) *sp; /* temporarily replace next chr with end of string */
*sp = '\0';
IsSetLearn = 0;
IsSetTest = 0;
IsSetDisable= 0;
if ( (strncmp (sp2, "learnfile" , 4 )) == 0) IsSetLearn = 1;
else if ( (strncmp (sp2, "recallfile", 4 )) == 0) IsSetTest = 1;
else if ( (strncmp (sp2, "testfile" , 4 )) == 0) IsSetTest = 1;
else if ( (strncmp (sp2, "disable" , 4 )) == 0) IsSetDisable=1;
*sp = (TEXT) i; /* restore the chr */
if (*sp == ',')
sp++; /* skip single comma */
for (; *sp <= 0x20 && *sp != '\0'; sp++); /* skip spaces after task id */
if (IsSetLearn)
sp2 = LearnFile;
else if (IsSetTest)
sp2 = TestFile;
else if (IsSetDisable)
break; /* no args, nothing to parse */
else {
fprintf (tmpFile, "FAILURE: unknown set command -> %s", input);
parsingError = 1;
break;
}
if ( (parsingError = parseString (&sp, sp2, &sp2[MAXFILESPEC])) == 1) {
fprintf (tmpFile, "FAILURE: missing quote -> %s", input);
break;
}
if (*sp2 == '\0') {
fprintf (tmpFile, "FAILURE: no filename specified -> %s", input);
parsingError = 1;
break;
}
if ( (parsingError = fileNotFound (sp2, ".nna", 0)) == 1) {
fprintf (tmpFile, "FAILURE: file does not exist -> %s", input);
break;
}
break;
case RANDOMSEED:
if ( (parsingError = parseInteger (&sp, &RandomSeed)) == 1)
fprintf (tmpFile, "FAILURE: random seed missing -> %s", input);
break;
case HOLDOUT:
parseReal (&sp, &SigmaStart); /* allow any number */
parsingError = parseReal (&sp, &SigmaStop); /* allow >= 0.0 */
if (parsingError && SigmaStop == 0.0)
parsingError = 0;
if (!parsingError)
parsingError = parseReal (&sp, &SigmaStep); /* disallow <= 0.0 */
if (!parsingError) {
if (SigmaStart > SigmaStop) {
fprintf (tmpFile, "FAILURE: sigmaStart > sigmaStop -> %s", input);
parsingError = 1;
}
else if (SigmaStep > SigmaStop) {
fprintf (tmpFile, "FAILURE: sigmaStop < sigmaStep -> %s", input);
parsingError = 1;
}
break;
}
fprintf (tmpFile, "FAILURE: start,stop,step needed -> %s", input);
parsingError = 1;
break;
default:
fprintf (tmpFile, "FAILURE: unrecognized task -> %s", input);
parsingError = 1;
break;
} /* end switch */
/* yield an error if too many fields were found */
if (!parsingError && *sp != '!' && *sp != '\0') {
fprintf (tmpFile, "FAILURE: too many fields -> %s", input);
parsingError = 1;
}
if (parsingError)
numErrors++;
else
fprintf (tmpFile, "%s", input);
} /* end while (runResult != UIO_EXIT) */
fclose (tmpFile);
fclose (inputFile);
remove ("automate.dat");
rename ("automate.tmp", "automate.dat");
#ifdef MAC
SetTypeAndCreator ("automate.dat", "TEXT", "ttxt", -1);
#endif
if (runResult == UIO_EXIT)
return (UIO_EXIT);
else if (numErrors > 0) {
sprintf (input, "ERROR: Automate.dat contains %ld syntax errors; press Enter to exit...", (SL)numErrors);
showMsg (input, 0);
GetStr ();
return (UIO_EXIT);
}
else {
showMsg ("no errors found; continuing.", 1);
return (UIO_OK);
}
}
#ifdef MAC
#define WINDOW_COLOR 7
#define TEXT_COLOR 4
#else
#define WINDOW_COLOR 4
#define TEXT_COLOR 7
#endif
/**************************************************************************/
/* processOneTask - do the deed. Global variables hold task parameters */
/**************************************************************************/
NINT processOneTask (taskID)
NINT taskID; /* task being processed */
{
APE peData; /* PE information for one PE, for disable */
TEXT title[150]; /* line containing task-in-progress info */
NINT windowColor; /* window color */
NINT textColor; /* text color */
TEXT buf[100]; /* work buffer for messages to user */
NINT runResult; /* return value from this routine */
TEXT *sp, *spend; /* string pointers */
NINT i, j; /* work indices */
NINT rc; /* return code */
runResult = TASK_OK; /* assume a successful task */
/* get graphics info & handle monochrome terminals */
ug_gparms (&xSize, &ySize, &i, &xChrSize, &yChrSize);
if (i < 8) {
windowColor = 1;
textColor = 0;
} else {
windowColor = WINDOW_COLOR;
textColor = TEXT_COLOR;
}
switch (taskID) {
case OPEN: /* open the network */
if (ug_loadnet (NetworkFile) != 0) {
runResult = TASK_ERROR; /* NWorks displays an error message here. */
break;
}
/* network is now loaded; add '.nnd' if necessary */
for (sp = NetworkFile; *sp != '.' && *sp != '\0'; sp++);
spend = &NetworkFile[MAXFILESPEC-4];
if (*sp != '.' && sp < spend)
sprintf (sp, ".nnd");
/* display the network and title line */
ug_windel (0); /* force network to display on screen */
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Network %s opened.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
/* obtain information about this network */
sp = buf; /* only 1 arg below is wanted */
ug_rdnetinf (&i, &NumInputPEs, &i, &i, &sp, &sp);
ug_randseed (0); /* reset so random file presentations stay same */
break;
case SAVENET:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Saving network %s.", SavenetFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
SaveNet (SavenetFile, 0); /* save in Binary mode */
break;
case LEARN:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Training network %s for %ld Learns.", NetworkFile, Long1);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
if ( (rc=ug_learn (Long1)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
else
SaveNet (NetworkFile, 0); /* save in Binary mode */
break;
case TEST:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Testing network %s.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
if ( (rc=ug_test (0l)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
break;
case RECALL:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Recalling network %s.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
if ( (rc=ug_recall (0l)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
break;
case SAVEBEST:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Training %s", NetworkFile);
sp = &title[strlen(title)];
if (Long1 != 0)
sprintf (sp, " for %ld learns.", Long1);
sp = &title[strlen(title)-1];
sprintf (sp, ", testing every %ld learns.", Long2);
i = strlen(title)*xChrSize; /* ensure title fits */
if ( i > xSize)
title[strlen(title)-8] = '\0'; /* remove ' learns.' if too long */
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
/* strip '.nnd' from string (if there) */
i = 0; /* temp flag indicating whether '.nnd' was stripped */
if (NetworkFile[strlen (NetworkFile)-4] == '.') {
NetworkFile[strlen (NetworkFile)-4] = '\0';
i = 1;
}
j = 0;
if (SbPruneTolerance > 0.0 && SbPruneMaxPEs > 0)
j = 1; /* temp flag == 1 if pruning parameters were entered */
/* note: assumes overwrite current net, logging */
if ((rc=ug_savebest (Long1, Long2, Long3, 1, NetworkFile,
j, SbPruneMaxPEs, SbPruneTolerance)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
if (i == 1) /* restore the '.nnd' part of the filename */
NetworkFile[strlen (NetworkFile)] = '.';
break;
case DISABLE_ALL: /* disable each input PE one at a time in turn. */
/* if IsSetDisable is set, then ONLY the PEs will be disabled. They are */
/* not re-enabled, and no test is performed. This is useful as a way to */
/* disable particular PEs and save the net with them disabled. It is */
/* assumed that a savenet command will be encountered before opening */
/* another network. */
if (!IsSetDisable && FirstDisableTask) {
/* upon first disable request, delete any previously existing graph output */
/* and perform the baseline test */
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Baseline test of network %s.", NetworkFile);
j = strlen(title)*xChrSize; /* center the title line */
j = (xSize - j) /2;
ug_puts (1, textColor, 0, j,yChrSize/4+1, title, 0);
remove ("disable.nnp");
if ((rc=ug_test (0l)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
if ( (disableOutput ()) != 0)
runResult = TASK_ERROR;
if (runResult != TASK_OK)
break;
FirstDisableTask = 0;
} /* end !IsSetDisable */
PeNumbers[1] = 0;
/* disable and test each PE in the input layer */
for (i=0; i < NumInputPEs; i++) {
ug_peio (&peData, 0, 0, i); /* read pe info (layer 0) */
if (peData.ape_Flags &= 0x0002) /* skip if already disabled */
continue;
peData.ape_Output = 0.0; /* set it's output to 0.0 */
peData.ape_Flags |= 0x0002; /* disable the PE */
ug_peio (&peData, 1, 0, i); /* write the pe info */
if (IsSetDisable) /* skip testing and re-enabling of PEs */
continue;
/* display the network showing the title line and disabled PE number */
PeNumbers[0] = i+2;
ug_windel (0); /* force network to display on screen */
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Testing %s with PE %ld disabled.", NetworkFile, (SL)PeNumbers[0]);
j = strlen(title)*xChrSize; /* center the title line */
j = (xSize - j) /2;
ug_puts (1, textColor, 0, j,yChrSize/4+1, title, 0);
/* perform a test command with this PE disabled */
if ((rc=ug_test (0l)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
/* enable the PE */
peData.ape_Flags &= ~0x0002; /* enable the PE */
ug_peio (&peData, 1, 0, i); /* write the pe info */
/* read disable.nnp and record results */
if ( (disableOutput ()) != 0)
runResult = TASK_ERROR;
if (runResult != TASK_OK)
return(runResult);
}
break;
case DISABLE: /* disable certain PEs entered on this task line */
/* if IsSetDisable is set, then ONLY the PEs will be disabled. They are */
/* not re-enabled, and no test is performed. This is useful as a way to */
/* disable particular PEs and save the net with them disabled. It is */
/* assumed that a savenet command will be encountered before opening */
/* another network. */
if (!IsSetDisable && FirstDisableTask) {
/* upon first disable request, delete any previously existing graph output */
/* and perform the baseline test */
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Baseline test of network %s.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
remove ("disable.nnp");
if ((rc=ug_test (0l)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
if ( (disableOutput ()) != 0)
runResult = TASK_ERROR;
FirstDisableTask = 0;
} /* end !IsSetDisable */
/* now processing the disable PE request. Note that an input layer's first PE */
/* is PE number 2. For example, IRIS networks have 4 inputs: PE2, PE3, PE4, */
/* and PE5. Internally this becomes 0 through 3 (the first PE of any layer */
/* number 0). */
/* disable the PEs */
for (i=0; i < DISABLEPES && PeNumbers[i] != 0; i++) {
ug_peio (&peData, 0, 0, PeNumbers[i]-2); /* read pe info (layer 0) */
if (!(peData.ape_Flags &= 0x0002)) { /* if not already disabled */
peData.ape_Output = 0.0; /* set it's output to 0.0 */
peData.ape_Flags |= 0x0002; /* disable the PE */
ug_peio (&peData, 1, 0, PeNumbers[i]-2); /* write the pe info */
}
else
PeNumbers[i] *= -1; /* mark this PE to prevent re-enabling */
}
if (IsSetDisable) /* skip testing and re-enabling of PEs */
break;
/* display the network showing the title line and first disabled PE */
ug_windel (0); /* force network to display on screen */
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
if (PeNumbers[0] > 0)
sprintf (title, "Testing %s with disabled PEs. (%ld)", NetworkFile, (SL)PeNumbers[0]);
else
sprintf (title, "Testing %s with disabled PEs. (%ld)", NetworkFile, (SL)(-PeNumbers[0]));
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
/* perform a test command with some PEs disabled */
if ((rc=ug_test (0l)) < 0)
runResult = TASK_ERROR;
else if (rc&USER_INTRPT)
runResult = TASK_INTRPT;
/* enable the PEs */
for (i=0; i < DISABLEPES && PeNumbers[i] != 0; i++)
if (PeNumbers[i] > 0) { /* skip PEs that were disabled to begin with */
ug_peio (&peData, 0, 0, PeNumbers[i]-2); /* read pe info (layer 0) */
peData.ape_Flags &= ~0x0002; /* enable the PE */
ug_peio (&peData, 1, 0, PeNumbers[i]-2); /* write the pe info */
}
else
PeNumbers[i] *= -1; /* unmark a previously disabled PE */
/* read disable.nnp and record results */
if ( (disableOutput ()) != 0)
runResult = TASK_ERROR;
if (runResult != TASK_OK)
return(runResult);
break;
case RANDOMSEED:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Resetting random seed for network %s.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
if ( (ug_randseed (RandomSeed)) != 0)
runResult = TASK_ERROR;
break;
case INITIALIZE:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
sprintf (title, "Initializing network %s.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
if ( (ug_netinit ()) != 0)
runResult = TASK_ERROR;
break;
case SETCMD:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize); /* title window */
if (IsSetLearn)
sprintf (title, "Setting Learn filename to %s.", LearnFile);
else if (IsSetTest)
sprintf (title, "Setting Test filename to %s.", TestFile);
else if (IsSetDisable)
sprintf (title, "Disabling requested PE(s).");
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
if (IsSetDisable)
break;
if (IsSetLearn) {
/* strip '.nna' if necessary. Note that ug_fileio () requires this */
if (LearnFile[strlen (LearnFile)-4] == '.')
LearnFile[strlen (LearnFile)-4] = '\0';
/* values of -1 below default to current IO/Parameters settings */
if ( (ug_fileio (LearnFile, 0, -1, -1, -1)) != 0)
runResult = TASK_ERROR;
}
else if (IsSetTest) {
/* strip '.nna' if necessary */
if (TestFile[strlen (TestFile)-4] == '.')
TestFile[strlen (TestFile)-4] = '\0';
if ( (ug_fileio (TestFile, 1, -1, -1, -1)) != 0)
runResult = TASK_ERROR;
}
break;
case HOLDOUT:
ug_window (1, windowColor, 0,ySize-((NINT)(yChrSize*1.6)), xSize,ySize);
sprintf (title, "Holdout Testing on %s.", NetworkFile);
i = strlen(title)*xChrSize; /* center the title line */
i = (xSize - i) /2;
ug_puts (1, textColor, 0, i,yChrSize/4+1, title, 0);
runResult = runHoldOut ();
break;
default:
runResult = TASK_ERROR;
break;
} /* end switch (taskID) */
return (runResult);
}
/**************************************************************************/
/* disableOutput - reads disable.nnp and appends to disable.log */
/**************************************************************************/
NINT disableOutput ()
{
TEXT input[NNPLINELEN]; /* long enough for a 9x9 confusion matrix */
SREAL value[DISABLEPES]; /* R values from confusion matrixes */
SREAL testSum; /* sum of R values */
NINT valueIndex; /* index into value array */
FILE *f1, *f2;
NINT i;
/* open i/o files */
if ( (f1 = fopen ("disable.nnp", "r")) == (FILE *)0) {
showMsg ("Can't open instrument file 'disable.nnp'.", 0);
return (TASK_ERROR);
}
if ( (f2 = fopen ("disable.log", "a")) == (FILE *)0) {
showMsg ("Can't open output file 'disable.log'.", 0);
return (TASK_ERROR);
}
/* read R correlation values */
valueIndex = -1;
while ((fgets (input, NNPLINELEN, f1)) != 0)
if (input[0] != '!' && input[0] != '\n') { /* skip comments and blanks */
for (i=strlen(input)-2; input[i] > 0x20; i--); /* find last value */
sscanf (&input[i], "%f", &value[++valueIndex]);
if (valueIndex+1 == DISABLEPES)
break;
}
valueIndex++;
/* write headings if this is first output since the network was opened */
if (FirstDisableTask) {
fprintf (f2, "!%s! network: %s%s", EolChr, NetworkFile, EolChr);
if (valueIndex > 1) {
fprintf (f2, "! sum R ");
for (i=0; i < valueIndex; i++)
fprintf (f2, " ConfM%ld ", (SL)(i+1));
}
else
fprintf (f2, "! R corr");
fprintf (f2, " %%impact ---disabled PEs---%s", EolChr);
}
/* subtotal the test results; remember baseline sum for later comparison */
testSum = 0.0;
for (i=0; i < valueIndex; i++)
testSum += value[i];
if (FirstDisableTask)
BaselineSum = testSum;
/* write outputs. NOTE: order of last access of the confusion matrixes */
/* (ConfM), when dealing with more than 1, is important! Before saving a */
/* network, users should edit and okay each in order: first the ConfM on */
/* the first (leftmost) output PE, then the second, etc. This is needed */
/* because the order of execution of graphs (i.e. the order listed into */
/* the *.nnp file) is based upon the creation or access order of the graphs. */
/* If this is NOT performed, disable.log may unknowingly switch around the */
/* output node results. */
if (valueIndex > 1)
fprintf (f2, "% 8.4f ", testSum); /* write sum of R */
for (i = 0; i < valueIndex; i++) /* write each output's R */
fprintf (f2, "% 6.4f ", value[i]);
/* write %impact (loss of accuracy caused by disabling these PEs) */
testSum /= BaselineSum;
testSum *= 100.0;
testSum = 100.0 - testSum;
fprintf (f2, "%7.3f ", testSum); /* will be negative if results improved */
if (FirstDisableTask)
fprintf (f2, " (baseline)");
else
for (i = 0; i < DISABLEPES && PeNumbers[i] != 0; i++)
fprintf (f2, " %ld", (SL)PeNumbers[i]);
fprintf (f2, "%s", EolChr);
fclose (f1);
fclose (f2);
#ifdef MAC
SetTypeAndCreator ("disable.log", "TEXT", "ttxt", -1);
#endif
remove ("disable.nnp");
return (TASK_OK);
}
/****************************************************************************/
/* runHoldOut - Search for optimum Sigma Scale factor for PNN and GRNN nets */
/****************************************************************************/
NINT runHoldOut ()
{
APE peData; /* PE structure; info for one PE */
ALYR layer; /* Layer structure; info for one layer */
ASCHED lrs; /* Schedule structure; info for one L/R Schedule */
NINT *winMap; /* dynamic memory pointer, 1 element per vector */
NINT *wwmp; /* work winMap pointer */
NINT *classCount; /* dynamic memory pointer, 1 element per output PE */
NINT *classCorrect; /* dynamic memory pointer, 1 element per output PE */
REAL rmsAccumulate; /* accumulator for GRNN rms measure */
NINT pnnLayer; /* layer number of PNN or GRNN layer in net */
NINT pnnPEs; /* number of PEs in PNN or GRNN layer */
NINT outputLayer; /* layer number of output layer in net */
NINT outputPEs; /* number of PEs in output layer */
NINT isPNN; /* flag whether PNN net or GRNN net */
SL testVectors; /* number of records in test data set */
SREAL highestOutput; /* highest pattern layer output value */
SREAL classRate; /* classification rate, if 1 of N outputs */
SREAL sigmaScale; /* current sigma scale setting */
FILE *logFile; /* output (appended) log file */
SL tmpLong; /* temp long */
TEXT *sp; /* temp string pointer */
NINT returnCode; /* return value */
TEXT errorMsg[100]; /* i/o error messages */
SREAL bestSigma; /* Best sigma from holdout */
SREAL bestMeasure; /* saves best result from holdout runs */
TEXT testFN[20]; /* Recall/Test file name */
NINT i;
winMap = (NINT *)0;
classCount = (NINT *)0;
classCorrect = (NINT *)0;
logFile = (FILE *)0;
testFN[0] = '\0';
bestSigma = 0.0;
/* open output log file */
if ((logFile = fopen ("holdout.log", "a")) == (FILE *)0) {
strcpy (errorMsg, "Can't open output file 'holdout.log'.");
goto taskError;
}
ug_rdfileinf (&sp, 1, &testVectors); /* fetch filename of test data */
strncpy(testFN, sp, 20); /* Save the file name */
testFN[19] = '\0'; /* so we retore it later */
/* fetch # vectors, and set Test command to run from the training file */
ug_rdfileinf (&sp, 0, &testVectors); /* fetch filename of learn data */
if (testVectors <= 0l) {
strcpy (errorMsg, "Error reading training data set (missing file?)");
goto taskError;
}
if ( (ug_fileio (sp, 1, -1, -1, -1)) != 0) { /* test from learn data set */
strcpy (errorMsg, "Unexpected error calling ug_fileio().");
goto taskError;
}
/* fetch output layer number & #PEs */
ug_rdnetinf (&outputLayer, &i, &outputPEs, &i, &sp, &sp);
outputLayer--;
/* allocate dynamic memory */
if ((winMap = (NINT *) malloc (sizeof(NINT)*testVectors)) == (NINT *)0) {
strcpy (errorMsg, "Insufficient memory for winMap array.");
goto taskError;
}
if ((classCount = (NINT *) malloc (sizeof(NINT)*outputPEs)) == (NINT *)0) {
strcpy (errorMsg, "Insufficient memory for classCount array.");
goto taskError;
}
if ((classCorrect = (NINT *) malloc (sizeof(NINT)*outputPEs)) == (NINT *)0) {
strcpy (errorMsg, "Insufficient memory for classCorrect array.");
goto taskError;
}
/* init arrays */
for (i=0; i < outputPEs; i++) {
classCount[i] = 0;
classCorrect[i] = 0;
}
/* locate the PNN or GRNN pattern layer and fetch #PEs */
pnnPEs = 0;
isPNN = 0;
for (i=1; i < outputLayer; i++) {
ug_lyrio (&layer, 0, i); /* read layer info for this layer */
/* 17 is PNN directory list item; 19 is GRNN directory list item */
if (layer.tran_f == 17 || layer.tran_f == 19) {
pnnLayer = i;
pnnPEs = layer.num_pes;
if (layer.tran_f == 17)
isPNN = 1;
break;
}
}
if (pnnPEs == 0) {
strcpy (errorMsg, "Can't find PNN/GRNN pattern layer (wrong net type?)");
goto taskError;
}
if (isPNN)
bestMeasure = -10000.0;
else
bestMeasure = 10000.0;
/* fetch current Sigma Scale coefficient from L/R schedule */
ug_schdio (&lrs, 0, pnnLayer);
sigmaScale = lrs.asc_col[0].asc_rcl[5];
/* setup sigma start,stop,step. A negative sigma start means that we */
/* will interpret the start/stop settings to be offsets from the current */
/* sigma scale (positive sigma start means absolute addressing, */
/* negative sigma start means relative addressing). Also, Sigma Scale */
/* should never become zero or less than zero. */
if (SigmaStart < 0.0) {
SigmaStart += sigmaScale;
if (SigmaStart < 0.00001)
SigmaStart = 0.00001;
SigmaStop += sigmaScale;
}
sigmaScale = SigmaStart;
/* write logfile headers */
fprintf (logFile, "Holdout testing of network %s%s", NetworkFile, EolChr);
fprintf (logFile,
"Sigma Scale varies from %6.4f to %6.4f, stepped by %6.4f%s",
SigmaStart, SigmaStop, SigmaStep, EolChr);
fflush(logFile);
/* run through training data; setup win map and count vectors per class */
for (tmpLong=0l, wwmp=winMap; tmpLong < testVectors; tmpLong++,wwmp++) {
if ((returnCode = ug_test (1l)) < 0) {
strcpy (errorMsg, "An error occurred running the Test command.");
goto taskError;
}
else if (returnCode & USER_INTRPT)
goto taskInterrupt;
highestOutput = -10000.0;
for (i=0; i < pnnPEs; i++) {
ug_peio (&peData, 0, pnnLayer, i); /* read PNN/GRNN layer PE */
if (peData.ape_Output > highestOutput) {
*wwmp = i; /* set winning PE # for this vector */
highestOutput = peData.ape_Output;
}
}
if (isPNN) {
for (i=0; i < outputPEs; i++) {
ug_peio (&peData, 0, outputLayer, i); /* read Output layer PE */
if (peData.ape_Err > .5) /* desired output */
classCount[i]++;
}
}
}
/* run holdout tests. Loop through data once per sigma scale setting */
while (1) {
rmsAccumulate = 0.0;
for (i=0; i < outputPEs; i++)
classCorrect[i] = 0;
/* write current Sigma Scale coefficient into L/R schedule */
if (sigmaScale < 0.00001)
sigmaScale = 0.00001; /* If < 0.00001 will use old Neuro-dynamics */
lrs.asc_col[0].asc_rcl[5] = sigmaScale;
ug_schdio (&lrs, 1, pnnLayer);
for (tmpLong=0l,wwmp=winMap; tmpLong < testVectors; tmpLong++,wwmp++) {
NINT highestIndex1, highestIndex2;
/* disable this vector's pattern layer PE */
ug_peio (&peData, 0, pnnLayer, *wwmp); /* read pe info */
peData.ape_Output = 0.0; /* zero it's output */
peData.ape_Flags |= 0x0002; /* disable the PE */
ug_peio (&peData, 1, pnnLayer, *wwmp); /* write PE info */
/* test this vector only, and accumulate RMS Error */
if ((returnCode = ug_test (1l)) < 0) {
strcpy (errorMsg, "An error occurred running the Test command.");
goto taskError;
} else if (returnCode & USER_INTRPT)
goto taskInterrupt;
highestOutput = -10000.0;
highestIndex1 = -1;
highestIndex2 = -1;
for (i=0; i < outputPEs; i++) {
APE wpe; /* work pe */
ug_peio (&wpe, 0, outputLayer, i); /* read Output layer PE */
if (isPNN) {
if (wpe.ape_Output > highestOutput) {
highestIndex1 = i;
highestOutput = wpe.ape_Output;
}
if (wpe.ape_Err > 0.5)
highestIndex2 = i;
} else { /* calculate rms for this vector */
rmsAccumulate +=
((wpe.ape_Err - wpe.ape_Output) *
(wpe.ape_Err - wpe.ape_Output)) / ((REAL)outputPEs);
}
}
if (isPNN &&
highestIndex1 >= 0 &&
highestIndex1==highestIndex2)
classCorrect[highestIndex1]++;
/* enable the PE */
peData.ape_Flags &= ~0x0002; /* enable the PE */
ug_peio (&peData, 1, pnnLayer, *wwmp); /* write PE info */
}
/* write log file results */
if (isPNN) { /* is PNN use classRate; if GRNN use rmsError */
classRate = 0.0;
for (i=0; i < outputPEs; i++) {
if (classCount[i] > 0)
classRate += classCorrect[i] / (SREAL)classCount[i];
}
classRate /= (SREAL)outputPEs;
if (classRate > bestMeasure) {
bestMeasure = classRate;
bestSigma = sigmaScale;
}
fprintf (logFile,
" avg classification rate = %6.4f, sigma scale = %6.4f%s",
classRate, sigmaScale, EolChr);
} else {
rmsAccumulate /= (double)(testVectors);
rmsAccumulate = sqrt(rmsAccumulate);
if (rmsAccumulate < bestMeasure) {
bestMeasure = rmsAccumulate;
bestSigma = sigmaScale;
}
fprintf (logFile,
" root-mean-square error = %6.4f, sigma scale = %6.4f%s",
rmsAccumulate, sigmaScale, EolChr);
}
fflush(logFile);
/* setup for next loop or exit from loop */
if (sigmaScale + SigmaStep <= SigmaStop)
sigmaScale += SigmaStep;
else if (sigmaScale < SigmaStop)
sigmaScale = SigmaStop;
else
break;
} /* end while (1) */
/* write best Sigma Scale coefficient into L/R schedule */
lrs.asc_col[0].asc_rcl[5] = bestSigma;
ug_schdio (&lrs, 1, pnnLayer);
returnCode = TASK_OK;
endRoutine:
if (logFile != (FILE *)0) {
fprintf (logFile, "%s", EolChr);
fclose (logFile);
#ifdef MAC
SetTypeAndCreator ("holdout.log", "TEXT", "ttxt", -1);
#endif
}
if (winMap != (NINT *)0)
free (winMap);
if (classCount != (NINT *)0)
free (classCount);
if (classCorrect != (NINT *)0)
free (classCorrect);
if (testFN[0] != '\0')
ug_fileio (testFN, 1, -1, -1, -1); /* Restore test file name */
return (returnCode);
taskError:
showMsg (" ", 1);
showMsg (errorMsg, 0);
if (logFile != (FILE *)0)
fprintf (logFile, "%s%s", errorMsg, EolChr);
returnCode = TASK_ERROR;
goto endRoutine;
taskInterrupt:
returnCode = TASK_INTRPT;
goto endRoutine;
}
/**************************************************************************/
/* parseString - extract a string (with or without quotes) from input */
/**************************************************************************/
NINT parseString (sp, sp2, spend)
TEXT **sp, *sp2, *spend; /* string pointers */
{
TEXT quoteChr;
NINT tooMuchData; /* flag == 1 if more data than array elements */
tooMuchData = 0;
*sp2 = '\0';
if (**sp == '"' || **sp == '\'') {
quoteChr = **sp;
for ((*sp)++; **sp != '\0' && **sp != quoteChr && sp2 < spend;
*sp2 = **sp, (*sp)++, sp2++); /* fill array */
if (**sp == quoteChr) {
*sp2 = '\0';
(*sp)++; /* skip quote */
if (**sp == ',') /* skip single comma */
(*sp)++;
for (; **sp <= 0x20 && **sp != '\0'; (*sp)++); /* skip spaces, etc */
return (0);
}
if (sp2 == spend) /* tooMuchData found */
for (; **sp > 0x20 && **sp != ',' && **sp != '!'; (*sp)++); /* skip digits */
if (**sp == ',') /* skip single comma */
(*sp)++;
for (; **sp <= 0x20 && **sp != '\0'; (*sp)++); /* skip spaces, etc */
return (1);
}
/* not quoted */
for (; **sp > 0x20 && **sp != ',' && **sp != '!' && sp2 < spend;
*sp2 = **sp, (*sp)++, sp2++); /* fill array */
*sp2 = '\0';
if (sp2 == spend && **sp > 0x20 && **sp != ',' && **sp != '!')
tooMuchData = 1;
if (sp2 == spend)
for (; **sp > 0x20 && **sp != ',' && **sp != '!'; (*sp)++); /* skip digits */
if (**sp == ',') /* skip single comma */
(*sp)++;
for (; **sp <= 0x20 && **sp != '\0'; (*sp)++); /* skip spaces, etc */
sp2--;
if (tooMuchData || *sp2 == '"' || *sp2 == '\'') {
return (1);
}
return (0);
}
/**************************************************************************/
/* parseLong - extract a Long numeric value from input */
/**************************************************************************/
NINT parseLong (sp, value)
TEXT **sp;
SL *value; /* returned number */
{
NINT rc;
if (sscanf(*sp, "%ld", value) <= 0) {
rc = 1;
*value = 0l;
} else
rc = 0;
for (; **sp > 0x20 && **sp != ',' && **sp != '!'; (*sp)++); /* skip digits */
if (**sp == ',')
(*sp)++; /* skip single comma */
for (; **sp <= 0x20 && **sp != '\0'; (*sp)++); /* skip spaces, etc */
/* Only return 0 if positive */
if (rc || (*value) <= 0l)
return(1);
else
return(0);
}
/**************************************************************************/
/* parseInteger - extract a Integer numeric value from input */
/**************************************************************************/
NINT parseInteger (sp, value)
TEXT **sp;
NINT *value; /* returned number */
{
SL wl; /* work long */
NINT rc;
if (sscanf(*sp, "%ld", &wl) <= 0) {
rc = 1;
*value = 0;
} else {
rc = 0;
*value = (NINT)wl;
}
for (; **sp > 0x20 && **sp != ',' && **sp != '!'; (*sp)++); /* skip digits */
if (**sp == ',')
(*sp)++; /* skip single comma */
for (; **sp <= 0x20 && **sp != '\0'; (*sp)++); /* skip spaces, etc */
/* Only return 0 if positive */
if (rc || (*value) <= 0)
return(1);
else
return(0);
}
/**************************************************************************/
/* parseReal - extract a Real (float) value from input */
/**************************************************************************/
NINT parseReal (sp, value)
TEXT **sp;
SREAL *value; /* returned number */
{
NINT rc;
if (sscanf(*sp, "%f", value) <= 0) {
*value = 0.0;
rc = 1;
} else
rc = 0;
for (; **sp > 0x20 && **sp != ',' && **sp != '!'; (*sp)++); /* skip digits */
if (**sp == ',')
(*sp)++; /* skip single comma */
for (; **sp <= 0x20 && **sp != '\0'; (*sp)++); /* skip spaces, etc */
/* Only return 0 if positive */
if (rc || (*value) <= 0.0)
return(1);
else
return(0);
}
/**************************************************************************/
/* fileNotFound - check to see file exists and can be opened */
/**************************************************************************/
NINT fileNotFound (fileName, defaultExt, extOptional)
TEXT *fileName, *defaultExt;
NINT extOptional; /* flag == 1 if filename extention is optional */
{
TEXT testName[MAXFILESPEC];
TEXT *sp;
FILE *testOpen;
/* note: this routine does NOT fixup bad file extentions! */
strcpy (testName, fileName);
if (extOptional) {
if ( (testOpen = fopen (testName, "r")) != (FILE *)0) {
fclose (testOpen);
return (0); /* good return; file does exist */
}
}
/* note: routine requires defaultExt passed with '.' and in lowercase! */
if (*defaultExt != '.')
return (1);
/* add default extention if name currently has no extention */
for (sp = testName; *sp != '.' && *sp != '\0'; sp++);
if (*sp != '.' && sp < &testName[MAXFILESPEC-4])
sprintf (sp, defaultExt); /* 'sp' now (probably) points at '.' */
sp++; /* ensure extentions are the same */
defaultExt++;
if ((TEXT)tolower(*sp) != *defaultExt)
return (1);
sp++;
defaultExt++;
if ((TEXT)tolower(*sp) != *defaultExt)
return (1);
sp++;
defaultExt++;
if ((TEXT)tolower(*sp) != *defaultExt)
return (1);
if ( (testOpen = fopen (testName, "r")) != (FILE *)0) {
fclose (testOpen);
return (0); /* good return; file does exist */
}
return (1); /* couldn't find it 'nohow' */
}
/**************************************************************************/
/* showMsg - displays message on screen */
/**************************************************************************/
VOID showMsg (text, eolFlag)
TEXT *text;
NINT eolFlag; /* 0=no eol; 1=eol */
{
PutStr (text); /* display to screen */
if (eolFlag == 1)
PutStr (EolChr); /* newline */
}
/**************************************************************************/
/* A User Control program needs the following functions only to avoid */
/* link errors. You do not need to provide code for any of them. */
/**************************************************************************/
NINT UIO_Learn_Start()
{
return(UIO_OK);
}
NINT UIO_Learn_Input(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Learn_Output(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Learn_Result(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Learn_End()
{
return(UIO_OK);
}
NINT UIO_Recall_Start()
{
return(UIO_OK);
}
NINT UIO_Read(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Write(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Write_Step(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Recall_Test(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_Recall_End()
{
return(UIO_OK);
}
NINT UIO_Instrument(Instrument_id, nDataElems, DataElemp)
NINT Instrument_id;
NINT nDataElems;
SREAL *DataElemp;
{
Instrument_id=Instrument_id; /* compiler be quiet! */
nDataElems=nDataElems; DataElemp=DataElemp; /* be quiet! */
return(UIO_OK);
}
NINT UIO_Rewind()
{
return(UIO_OK);
}
NINT UIO_Explain(LayN, nPEs, Datap)
NINT LayN;
NINT nPEs;
SREAL *Datap;
{
LayN=LayN; nPEs=nPEs; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
NINT UIO_ObjFunc(eoeflag, Datap)
NINT eoeflag;
SREAL *Datap;
{
eoeflag=eoeflag; Datap=Datap; /* compiler be quiet! */
return(UIO_OK);
}
#ifdef MAC
OSType string2OSType (char *s)
{
OSType *ret;
ret = (OSType *)s;
return (*ret);
}
OSErr SetTypeAndCreator (char *fnp, char *typ, char *crea, short vref)
{
OSErr err;
FInfo finfo;
OSType type, creator;
Str255 name;
if (vref == -1) { /* get current vref and use it */
if ((err = GetVol(&name[0],&vref)) != noErr)
return err;
}
err = GetFInfo( (StringPtr) c2pstr(fnp), vref, &finfo );
if (err == noErr) {
type = string2OSType (typ);
creator = string2OSType (crea);
if (finfo.fdType != type || finfo.fdCreator != creator) {
finfo.fdType = type;
finfo.fdCreator = creator;
err = SetFInfo((StringPtr) fnp, vref, &finfo);
}
}
p2cstr(fnp);
return err;
}
#endif /* MAC */